grammar TodoLangGrammar;
import ReportLexer;

entry :	expression+ EOF;

expression : exprComposite
		   | ifExpr
		   | caseExpr
		   | returnExpr
		   | variableAssign
		   ;

exprComposite : expr 								#singleExprComposite
			  | ternaryExpr							#ternaryExprComposite
			  | LeftP exprComposite RightP 			#parenExprComposite
			  | exprComposite OPER exprComposite	#complexExprComposite
			  ;

ternaryExpr : ifCondition (join ifCondition)* '?' block ':' block ; 

caseExpr : 'case' '{' casePart (',' casePart)* '}' ;

casePart : ifCondition (join ifCondition)* ':'? block ;

ifExpr: ifPart elseIfPart* elsePart? ;

ifPart : 'if' '(' ifCondition (join ifCondition)* ')' '{' block '}';

elseIfPart : 'else' 'if' '(' ifCondition (join ifCondition)* ')' '{' block '}' ;

elsePart : 'else' '{' block '}' ;

block : exprBlock* returnExpr? ;

exprBlock : variableAssign
		 | ifExpr
		 | caseExpr
		 ;

returnExpr : 'return'? expr ';'?;

expr : item (OPER item)* ;

ifCondition : expr OP expr ;
     
variableAssign : 'var'? variable '=' expr ';'?;

item : unit 				#simpleJoin
	 | LeftP item RightP					#singleParenJoin
     | LeftP item (OPER item)+ RightP		#parenJoin
     ;

unit : dataset
	 | function
	 | set
	 | cellPosition
	 | relativeCell
	 | currentCellValue
	 | currentCellData
	 | cell
	 | variable
	 | INT
	 | BOOLEAN
	 | STRING
	 | NUMBER
	 | NULL
	 ;

variable : IDEN ;

cellPosition : '&'CELL ;//表示单元格位置

relativeCell : '$'CELL ; //表示当前引用对应的单元格的值

currentCellValue : '#' ;//表示当前单元格值

currentCellData : '#''.'property ;//表示取当前单元绑定对象的某个属性值

cell : 'cell' ('.'property)? ;

dataset : IDEN '.' aggregate '(' datasetColumn? (',' conditions )? (',' ORDER)? ')';

datasetColumn  : property
              | IDEN '(' property (',' expr)* ')'
              | INT ;

function : IDEN '(' functionParameter? ')' ;

functionParameter : expr (',' expr)* ;

set : simpleValue										#simpleData
	| CELL												#singleCell
	| CELL '['']'('{' conditions '}')?					#wholeCell
	| CELL ':' CELL										#cellPair
	| CELL '{' conditions '}'							#singleCellCondition
	| CELL '[' cellCoordinate ']'						#singleCellCoordinate
	| CELL '[' cellCoordinate ']' '{' conditions '}'	#cellCoordinateCondition
	| set 'to' set										#range
	;

cellCoordinate : coordinateLeft? (';' coordinateTop)? ;

coordinateLeft : coordinate;

coordinateTop : coordinate;

coordinate : cellIndicator (',' cellIndicator)* ;

cellIndicator : CELL						#relative
			  | CELL ':' NOT? INT			#absolute
			  ;
	
conditions : condition (join condition)* ;
		
condition : CELL OP expr 				#cellNameExprCondition
		  | property OP expr			#propertyCondition
		  | currentValue OP expr		#currentValueCondition
		  | expr OP expr				#exprCondition
		  ;	  

property : IDEN
         | COLUMN
		 | property '.' property
		 ;

currentValue : '@' ;

simpleValue : INT|NUMBER|STRING|BOOLEAN|NULL;

join : AND | OR ;

aggregate : IDEN;